package impl;

import Clases.CriterioOrdenamiento;
import Clases.Libro;
import TDA.LibrosTDA;

public class LibrosImpl implements LibrosTDA {

	private CriterioOrdenamiento criterioOrd;
	
	private class Nodo {
		Libro raiz;          
		LibrosTDA librosHijoIzq;          
		LibrosTDA librosHijoDer; 
	}
	      
	Nodo nodoRaiz;
	
	public void InicializarLibros(CriterioOrdenamiento c) {
		nodoRaiz = null;
		this.criterioOrd = c;
	}

	public void AgregarLibro(Libro l) { 
		if(nodoRaiz == null){
			nodoRaiz = new Nodo();
			nodoRaiz.raiz = l;
			nodoRaiz.librosHijoDer = new LibrosImpl();
			nodoRaiz.librosHijoIzq = new LibrosImpl();
			nodoRaiz.librosHijoDer.InicializarLibros(criterioOrd);
			nodoRaiz.librosHijoIzq.InicializarLibros(criterioOrd);
			System.out.println("Se agrego el libro !!!");
		}else{
			if(criterioOrd == CriterioOrdenamiento.PRECIO){
				if(raiz().getPrecio() > l.getPrecio()){
					nodoRaiz.librosHijoIzq.AgregarLibro(l);
				}else if(raiz().getPrecio() < l.getPrecio()){
					nodoRaiz.librosHijoDer.AgregarLibro(l);
				} // considero que no se puede agregar un libro con el mismo precio que otro
			}else if(criterioOrd == CriterioOrdenamiento.NOMBRE){
				if(raiz().getNombre().compareTo(l.getNombre()) > 0){
					nodoRaiz.librosHijoIzq.AgregarLibro(l);
				}else if(raiz().getNombre().compareTo(l.getNombre()) < 0){
					nodoRaiz.librosHijoDer.AgregarLibro(l);
				} //si tienen en el mismo nombre no lo agrego.
			}	
		}	
	}        

	
	public void ElimnarLibro(Libro l) {
		if(nodoRaiz != null) {
			if(criterioOrd==CriterioOrdenamiento.NOMBRE){
				if(nodoRaiz.raiz.getNombre().compareTo(l.getNombre())==0 && nodoRaiz.librosHijoIzq.LibrosVacios()&&
						nodoRaiz.librosHijoDer.LibrosVacios()){
					nodoRaiz = null;
				} else {
					if(nodoRaiz.raiz.getNombre().compareTo(l.getNombre())==0 && !nodoRaiz.librosHijoIzq.LibrosVacios()){
						nodoRaiz.raiz = mayor(nodoRaiz.librosHijoIzq);
						nodoRaiz.librosHijoIzq.ElimnarLibro(nodoRaiz.raiz);
					}else{
						if(nodoRaiz.raiz.getNombre().compareTo(l.getNombre())==0 && nodoRaiz.librosHijoIzq.LibrosVacios()){
							nodoRaiz.raiz = menor(nodoRaiz.librosHijoDer);
							nodoRaiz.librosHijoDer.ElimnarLibro(nodoRaiz.raiz);
						} else {
							if(nodoRaiz.raiz.getNombre().compareTo(l.getNombre())>0){
								nodoRaiz.librosHijoIzq.ElimnarLibro(l);
							} else {
								nodoRaiz.librosHijoDer.ElimnarLibro(l);
							}
						}
					}
				}
			} else {
				if(criterioOrd == CriterioOrdenamiento.PRECIO){
					//considere que no hay libros con el mismo precio
					if(nodoRaiz.raiz.getPrecio()==l.getPrecio()&& nodoRaiz.librosHijoIzq.LibrosVacios()&&
							nodoRaiz.librosHijoDer.LibrosVacios()){
						nodoRaiz = null;
					} else {
						if(nodoRaiz.raiz.getPrecio()==l.getPrecio() && !nodoRaiz.librosHijoIzq.LibrosVacios()){
							nodoRaiz.raiz = mayor(nodoRaiz.librosHijoIzq);
							nodoRaiz.librosHijoIzq.ElimnarLibro(nodoRaiz.raiz);
						}else{
							if(nodoRaiz.raiz.getPrecio()==l.getPrecio() && nodoRaiz.librosHijoIzq.LibrosVacios()){
								nodoRaiz.raiz = menor(nodoRaiz.librosHijoDer);
								nodoRaiz.librosHijoDer.ElimnarLibro(nodoRaiz.raiz);
							} else {
								if(nodoRaiz.raiz.getPrecio()<l.getPrecio()){
									nodoRaiz.librosHijoDer.ElimnarLibro(l);
								} else {
									nodoRaiz.librosHijoIzq.ElimnarLibro(l);
								}
							}
						}
					}
				}
			}
		} 
	}                               
	
	private Libro menor(LibrosTDA libros) {
		if(libros.LibrosHijoIzq().LibrosVacios())
			return libros.raiz();
		else
			return menor(libros.LibrosHijoIzq());
	}

	private Libro mayor(LibrosTDA libros) {
		if(libros.LibrosHijoDer().LibrosVacios())
			return libros.raiz();
		else
			return mayor(libros.LibrosHijoDer());
	}
	

	public LibrosTDA LibrosHijoIzq() {                  
		return nodoRaiz.librosHijoIzq;          
	}            
	
	public LibrosTDA LibrosHijoDer() {                  
		return nodoRaiz.librosHijoDer;  
	}
	
	public boolean LibrosVacios() {                  
		return nodoRaiz == null;          
	}                     
	
	public Libro raiz() {                  
		return nodoRaiz.raiz;   
	}

}
